/*
 * Copyright (c) 2010-2020 Belledonne Communications SARL.
 *
 * This file is part of linphone-android
 * (see https://www.linphone.org).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.newlink.building.activities.call

import android.Manifest
import android.annotation.TargetApi
import android.app.KeyguardManager
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.view.Gravity
import android.view.WindowManager
import androidx.activity.result.contract.ActivityResultContracts
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.newlink.building.library_rino.ConnectionController
import com.newlink.building.library_rino.utils.RinoAudioUtils
import com.newlink.building.common_base.base.BaseApplication
import com.newlink.building.common_base.constant.Base_DeviceType
import com.newlink.building.common_base.constant.Base_RouterPath
import com.newlink.building.common_base.event.MessageEvent
import com.newlink.building.common_base.event.TYPE_CALL_SEND_CREATE_CHANNEL_RESULT_INCOMING_EARLYMEDIA
import com.newlink.building.common_base.event.TYPE_INCOMING_CALL_RECEIVE
import com.newlink.building.common_base.ext.showToast
import com.newlink.building.common_base.utils.DialogUtil
import com.newlink.building.common_base.utils.RomUtils
import com.newlink.building.NL_App.Companion.coreContext
import com.newlink.building.R
import com.newlink.building.activities.Module_Phone_GenericActivity
import com.newlink.building.activities.call.viewmodels.IncomingCallViewModel
import com.newlink.building.activities.call.viewmodels.IncomingCallViewModelFactory
import com.newlink.building.bean.Module_Phone_TitleBarBean
import com.newlink.building.compatibility.Module_Phone_Compatibility
import com.newlink.building.databinding.CallIncomingActivityBinding
import com.newlink.building.manager.Module_Phone_VoipController
import com.newlink.building.utils.Module_Phone_PermissionHelper
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationHelper
import com.newlink.building.obfuscation.Module_Obfuscation_ObfuscationInvoker
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.linphone.core.Call
import org.linphone.core.tools.Log
import org.linphone.mediastream.Version


/**
 * @author wangyang
 * @date 2022/11/21
 * @description 来电页面
 */
@Route(path = Base_RouterPath.PATH_INCOMINGCALL)
class Module_Phone_IncomingCallActivity : Module_Phone_GenericActivity() {
    private lateinit var binding: CallIncomingActivityBinding
    private lateinit var viewModel: IncomingCallViewModel
    private lateinit var mTitleBarBean: Module_Phone_TitleBarBean
    private val rinoManager: ConnectionController by lazy {
        ConnectionController.getInstance(
            applicationContext
        )
    }
    private var keyguardManager: KeyguardManager? = null
    private var keyguardLock: KeyguardManager.KeyguardLock? = null
    private var mPermissionLaunch =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            // 处理结果
            if (!Module_Phone_PermissionHelper.get().hasRecordAudioPermission()) {
//                    jumpToCapture()
                checkPermissions()
//                showToast(getString(R.string.permission_content_audio))
//                viewModel.terminateCall()
            }

        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 来电页面初始化时的混淆
        Module_Obfuscation_ObfuscationHelper.onMethodEnter("IncomingCallActivity", "onCreate")
        Module_Obfuscation_ObfuscationInvoker.invokeRandom(System.currentTimeMillis())

        val attributes = window.attributes
        attributes.flags =
            (WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

        EventBus.getDefault().register(this)
        coreContext.inInComingCallOrOutgoingCallActivity = true
        dismissKeyguard()

        if (RomUtils.isVivo()) {
            if (!RinoAudioUtils.isSpeakerphoneOn(this)) {
                RinoAudioUtils.choiceAudioModel(this, true)
            }
        }

        binding = DataBindingUtil.setContentView(this, R.layout.call_incoming_activity)
        binding.lifecycleOwner = this

        val incomingCall: Call? = findIncomingCall()
        if (incomingCall == null) {
            Log.e("[Incoming Call Activity] Couldn't find call in state Incoming")
            if (isTaskRoot) {
                Log.i("[Incoming Call Activity] Task is root, starting MainActivity")
//                ARouter.getInstance().build(RouterPath.PATH_HOME).withFlags(Intent.FLAG_ACTIVITY_NEW_TASK).navigation()
                // When resuming app from recent tasks make sure LinphoneMainActivity will be launched if there is no call
            }
            finish()
            return
        }
        EventBus.getDefault().post(MessageEvent(TYPE_INCOMING_CALL_RECEIVE, 0))
        viewModel = ViewModelProvider(
            this,
            IncomingCallViewModelFactory(incomingCall)
        )[IncomingCallViewModel::class.java]
        binding.viewModel = viewModel

        val remoteDeviceData =
            BaseApplication.getDeviceDataByUsername(
                Module_Phone_VoipController.get().getRemoteSipAccount(incomingCall)
            )
        Log.e("[Incoming Call Activity]  devName:${remoteDeviceData?.devName}  aid:${remoteDeviceData?.aid} devType:${remoteDeviceData?.devType}")
        //根据缓存的设备类型判断,如果是室内机和话机则语音接听
//        if (remoteDeviceData?.devType == DeviceType.INDOOR.code || remoteDeviceData?.devType == DeviceType.IPPHONE.code) {
//            viewModel.inComingCallIsVideoEnable.value = false
//        }
        if (remoteDeviceData?.devType == Base_DeviceType.INDOOR.code) {
            viewModel.inComingCallIsVideoEnable.value = false
        }
        //只有远端是门禁的时候设置视频预览
//        LinPhoneApp.corePreferences.acceptEarlyMedia = remoteDeviceData?.devType == DeviceType.DOORPHONE.code

        binding.ivOpenDoor.setOnClickListener {
            openDoor()
        }
        binding.answerVideoAccept.setOnClickListener {
            viewModel.answerCall(true)
        }
        binding.answerAudioAccept.setOnClickListener {
            viewModel.answerCall(false)
        }
        binding.hangUp.setOnClickListener {
            viewModel.terminateCall()
            finish()
        }
        binding.ivOpenDoorEarlyMedia.setOnClickListener {
            openDoor()
        }
        binding.answerVideoAcceptEarlyMedia.setOnClickListener {
            rinoManager.releasePlayer(false)
            viewModel.answerCall(true)
        }
        binding.answerAudioAcceptEarlyMedia.setOnClickListener {
            viewModel.answerCall(false)
        }
        binding.hangUpEarlyMedia.setOnClickListener {
            viewModel.terminateCall()
            finish()
        }

        viewModel.curCallRemoteDisplayName.observe(this) {
            mTitleBarBean = Module_Phone_TitleBarBean()
            mTitleBarBean.isShowCenterText.value = true

            mTitleBarBean.centerContent.value = it
            binding.titleBarBean = mTitleBarBean
        }

        viewModel.callEndedEvent.observe(
            this
        ) {
            it.consume {
                Log.i("[Incoming Call Activity] Call ended, finish activity")
                if (coreContext.core.callsNb == 0) {
                    finish()
                }
            }
        }

        viewModel.callConnectedEvent.observe(
            this
        ) {
            it.consume {
                Log.i("[Incoming Call Activity] Call connected, finish activity")
                finish()
            }
        }

        viewModel.earlyMediaVideoEnabled.observe(
            this
        ) {
            if (it) {
                Log.i("[Incoming Call Activity] Early media video being received, set native window id")
//                coreContext.core.nativeVideoWindowId = binding.textureViewRemote
                createIncomingEarlyMediaRinoChannel()
            } else {
                createIncomingRinoChannel()
            }
        }

//
//        val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
//        val keyguardLocked = keyguardManager.isKeyguardLocked
//        viewModel.screenLocked.value = keyguardLocked
//        if (keyguardLocked) {
//            // Forbid screen rotation to prevent keyguard to show up above incoming call view
//            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
//        }
//
//        binding.buttons.setViewModel(viewModel)

        if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
            checkPermissions()
        }

    }

    private fun dismissKeyguard() {
//        // Leaks on API 27+: https://stackoverflow.com/questions/60477120/keyguardmanager-memory-leak
//        Compatibility.requestDismissKeyguard(this)
        Module_Phone_Compatibility.setShowWhenLocked(this, true)
        Module_Phone_Compatibility.setTurnScreenOn(this, true)
        keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        if (keyguardManager?.isKeyguardLocked == true) {
            keyguardLock = keyguardManager?.newKeyguardLock("MyKeyguard")
            keyguardLock?.disableKeyguard()
        }

    }

    private fun releaseKeyguard() {

        if (keyguardLock != null) {
            keyguardLock?.reenableKeyguard()
            keyguardLock = null
        }

        if (keyguardManager != null) {
            keyguardManager = null
        }
    }


    private fun createIncomingRinoChannel() {
    }

    private fun createIncomingEarlyMediaRinoChannel() {
        rinoManager.setMuteAudio(true)
        rinoManager.setMicEnabled(false)
        if (rinoManager.getChannelName() != null) {
            rinoManager.joinChannel(binding.textureViewRemote, agoraId)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMsgReceived(event: MessageEvent) {

        when (event.msgType) {
            TYPE_CALL_SEND_CREATE_CHANNEL_RESULT_INCOMING_EARLYMEDIA -> {
                Log.e("[Incoming Call Activity] TYPE_CALL_SEND_CREATE_CHANNEL_RESULT_INCOMING_EARLYMEDIA")
                if (findIncomingCall() != null) {
                    rinoManager.joinChannel(binding.textureViewRemote, agoraId)
                }
            }
        }
    }

    override fun onResume() {
        super.onResume()
        val incomingCall: Call? = findIncomingCall()
        if (incomingCall == null) {
            Log.e("[Incoming Call Activity] Couldn't find call in state Incoming")
            if (isTaskRoot) {
                Log.i("[Incoming Call Activity] Task is root, starting MainActivity")
                // When resuming app from recent tasks make sure LinphoneMainActivity will be launched if there is no call
                ARouter.getInstance().build(Base_RouterPath.PATH_HOME)
                    .withFlags(Intent.FLAG_ACTIVITY_NEW_TASK).navigation()
            }
            finish()
        }

        var displayName = coreContext.core.currentCall?.remoteAddress?.username
        if (displayName.isNullOrEmpty()) {
            displayName = coreContext.core.currentCall?.remoteAddress?.domain
        }
//        GlobalScope.launch {
//            var findContactBySipAccount =
//                displayName?.let {
//                    LinPhoneApp.contactRepository.findContactBySipAccount(
//                        it
//                    )
//                }
//
//            withContext(Dispatchers.Main) {
//                if (findContactBySipAccount?.deviceType == DeviceType.ACCESS_CONTROL.code &&
//                    findContactBySipAccount?.enableOpenDoor
//                ) {
//                    binding.ivOpenDoor.visibility = View.VISIBLE
//                    binding.ivOpenDoorEarlyMedia.visibility = View.VISIBLE
//                } else {
//                    binding.ivOpenDoor.visibility = View.GONE
//                    binding.ivOpenDoorEarlyMedia.visibility = View.GONE
//                }
//            }
//        }
    }

    override fun onDestroy() {
        coreContext.inInComingCallOrOutgoingCallActivity = false
        mPermissionLaunch.unregister()
        EventBus.getDefault().unregister(this)
        super.onDestroy()
        releaseKeyguard()
    }

    @TargetApi(Version.API23_MARSHMALLOW_60)
    private fun checkPermissions() {
        val permissionsRequiredList = arrayListOf<String>()

        if (!Module_Phone_PermissionHelper.get().hasRecordAudioPermission()) {
            Log.i("[Incoming Call Activity] Asking for RECORD_AUDIO permission")
            permissionsRequiredList.add(Manifest.permission.RECORD_AUDIO)
        }

//        if (!PermissionHelper.get().hasCameraPermission()
//        ) {
//            Log.i("[Incoming Call Activity] Asking for CAMERA permission")
//            permissionsRequiredList.add(Manifest.permission.CAMERA)
//        }

//        if (Version.sdkAboveOrEqual(Version.API31_ANDROID_12) && !PermissionHelper.get()
//            .hasBluetoothConnectPermission()
//        ) {
//            Log.i("[Incoming Call Activity] Asking for BLUETOOTH_CONNECT permission")
//            permissionsRequiredList.add(Compatibility.BLUETOOTH_CONNECT)
//        }

        if (permissionsRequiredList.isNotEmpty()) {
            val permissionsRequired = arrayOfNulls<String>(permissionsRequiredList.size)
            permissionsRequiredList.toArray(permissionsRequired)
            requestPermissions(permissionsRequired, 0)
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == 0) {
            for (i in permissions.indices) {
                when (permissions[i]) {
                    Manifest.permission.RECORD_AUDIO -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        Log.i("[Incoming Call Activity] RECORD_AUDIO permission has been granted")
                    } else {
//                        showToast(getString(R.string.permission_content_audio))
//                        viewModel.terminateCall()
                        showPermissionDialog()
                    }

                    Manifest.permission.CAMERA -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        Log.i("[Incoming Call Activity] CAMERA permission has been granted")
                        coreContext.core.reloadVideoDevices()
                    } else {
                        showToast(getString(R.string.permission_content_camera))
                        viewModel.terminateCall()
                    }

                    Module_Phone_Compatibility.BLUETOOTH_CONNECT -> if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        Log.i("[Incoming Call Activity] BLUETOOTH_CONNECT permission has been granted")
                    } else {
                        showToast(getString(R.string.permission_content_bluetooth))
                        viewModel.terminateCall()
                    }
                }
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }

    private fun showPermissionDialog() {
        val mDialog = DialogUtil.getMessageDialog(
            this,
            getString(R.string.permission_content_audio),
            object : DialogInterface.OnClickListener {
                override fun onClick(dialog: DialogInterface?, which: Int) {
                    val intent = Intent()
                    intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
                    val uri = Uri.fromParts("package", packageName, null)
                    intent.data = uri
                    mPermissionLaunch.launch(intent)
                }
            }).show()
        mDialog.window?.run {
            attributes = attributes.apply {
                width = (windowManager.defaultDisplay.width * 0.95).toInt()
                gravity = Gravity.CENTER
            }
        }
    }

    private fun findIncomingCall(): Call? {
        for (call in coreContext.core.calls) {
            if (call.state == Call.State.IncomingReceived ||
                call.state == Call.State.IncomingEarlyMedia
            ) {
                return call
            }
        }
        return null
    }

    private fun openDoor() {
        var lockList: ArrayList<String> = ArrayList<String>()
        var displayName = coreContext.core.currentCall?.remoteAddress?.username
        if (displayName.isNullOrEmpty()) {
            displayName = coreContext.core.currentCall?.remoteAddress?.domain
        }
//        GlobalScope.launch {
//            var findContactBySipAccount =
//                displayName?.let {
//                    LinPhoneApp.contactRepository.findContactBySipAccount(
//                        it
//                    )
//                }
//
//            var findRelayById = findContactBySipAccount?._id?.let {
//                LinPhoneApp.contactRepository.queryRelay(
//                    it
//                )
//            }
//            if (findRelayById?.size == 1) {
//                var relayEntity = findRelayById[0]
//                if (relayEntity.unlocktype == 0) {
//                    coreContext.core.currentCall?.sendDtmfs(relayEntity.dtmfcode)
//                } else {
//                    DeviceUtils.excuteOpenDoorCommand(relayEntity.httpcommand)
//                }
//                return@launch
//            }
//            if (findRelayById != null) {
//                for (tempdata in findRelayById) {
//                    lockList.add(tempdata.name)
//                }
//            }
//            withContext(Dispatchers.Main) {
//                showOpenDoorModeListBottomSheetDialog(lockList)
//            }
//        }
    }

    override fun onBackPressed() {

    }

//    private fun showOpenDoorModeListBottomSheetDialog(lockList: ArrayList<String>) {
//        val bottomSheetDialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
//        bottomSheetDialog.setCanceledOnTouchOutside(true)
//        val view = LayoutInflater.from(this)
//            .inflate(R.layout.dialog_lock_select, null, false)
//        val recyclerView = view.findViewById(R.id.locksRecyclerView) as RecyclerView
//        view.findViewById<ImageView>(R.id.image_cancel).setOnClickListener {
//            bottomSheetDialog.dismiss()
//        }
//        val lockListAdapter = OpenDoorModeListAdapter(this, lockList, bottomSheetDialog)
//        recyclerView.adapter = lockListAdapter
//        recyclerView.addItemDecoration(SpaceItemDecoration(this))
//
//        bottomSheetDialog.setContentView(view)
//        bottomSheetDialog.show()
//    }
}
